<?php
/**
 * Base controller for tree data management. Tree algorythm is 
 * nested sets (http://en.wikipedia.org/wiki/Nested_set_model) 
 * 
 * @author Konstantin Shamko <konstantin.shamko@gmail.com> 
 * @version 0.0.1
 * @copyright  Copyright (c) 2009 Konstantin Shamko
 * @category VaselinEngine
 * @package Bel Classes
 * @license  New BSD License
 *
 */
abstract class Bel_Controller_Tree extends Bel_Controller {	
	
	/**
	 * Data model (instance of Bel_Model_Tree children)
	 *
	 * @var Bel_Model_Tree
	 */
	protected $_tree;
		
	/**
	 * Name of a smarty template to display tree
	 *
	 * @var string
	 */
	protected $_tree_template;
	
	/**
	 * Name of the form to add/edit tree node
	 *
	 * @var string
	 */
	protected $_formname;
	
	/**
	 * Add form action
	 *
	 * @var string
	 */
	protected $_form_add_action;
	
	/**
	 * Edit form action
	 *
	 * @var string
	 */
	protected $_form_edit_action;
	
	/**
	 * URL to show data grid 
	 * 
	 * @var string
	 */
	protected $_default_action;	
	
	/**
	 * Template with add/edit form
	 *
	 * @var string
	 */	
	protected $_form_template = 'forms/default.tpl';
		
	/**
	 * URL to show add form
	 *
	 * @var string
	 */
	protected $_add_form_action;
		
	/**
	 * URL to show edit form
	 *
	 * @var string
	 */
	protected $_edit_form_action;	
	
	/**
	 * Name of the smarty template with form to move tree nodes
	 *
	 * @var string
	 */
	protected $_move_form_template;	
	
	/**
	 * Name of a primary key field. Setted automatically
	 *
	 * @var string
	 */
	protected $_id_field;	
	
	/**
	 * Object init
	 *
	 * @return void
	 */	
	public function init() {
		$this->_formdata = new Zend_Session_Namespace ( 'formdata' );
		parent::init ();
		$this->_id_field = $this->_tree->getIdCol ();

		$module = $this->_request->getModuleName();
		$controller = $this->_request->getControllerName();
		
		$this->_form_add_action = '/'.$module.'/'.$controller.'/addnode/';
		$this->_form_edit_action = '/'.$module.'/'.$controller.'/editnode/';			
		$this->_default_action = '/'.$module.'/'.$controller.'/';
		$this->_add_form_action = '/'.$module.'/'.$controller.'/addform/';
		$this->_edit_form_action = '/'.$module.'/'.$controller.'/editform/';
	}	
	
	/**
	 * Displays tree
	 * 
	 * @return void
	 */
	public function indexAction() {
		$this->view->assign ( 'tree', $this->_tree->getTree () );
		$this->view->display ( $this->_tree_template );
	}	
	
	/**
	 * Displays add form for node
	 * 
	 * @return void
	 */
	public function addformAction() {
		if (($messages = $this->_messages->getMessages ())) {
			$this->view->assign ( 'messages', $messages );
		}
		
		$form = new Bel_Forms_Builder ( $this->_formname, $this->_form_add_action );
		$form->addElement ( 'hidden', $this->_id_field, array ('value' => $this->_request->getParam ( $this->_id_field ) ) );
		
		if ($this->_formdata->request) {
			$form->populateForm ( $this->_formdata->request );
			$this->_formdata->unsetAll ();
		}
		$this->view->assign ( 'form', $form );
		$this->view->display ( $this->_form_template );
	}
	
	/**
	 * Displays edit form for node
	 * 
	 * @return void
	 */
	public function editformAction() {
		if (($messages = $this->_messages->getMessages ())) {
			$this->view->assign ( 'messages', $messages );
		}
		
		$info = $this->_tree->getNodeInfo ( $this->_request->getParam ( $this->_id_field ) );
		$form = new Bel_Forms_Builder ( $this->_formname, $this->_form_edit_action );
		$form->addElement ( 'hidden', $this->_id_field, array ('value' => $info->{$this->_id_field} ) );
		$form->populateForm ( $info );
		$this->view->assign ( 'form', $form );
		$this->view->display ( $this->_form_template );
	}	
	
	/**
	 * Adds tree node to a DB
	 *
	 * @return void
	 */
	public function addnodeAction() {
		if ($this->_validator->validate ( $this->_formname, $this->_request->getParams () )) {
			$this->_tree->addNode ( $this->_request->getParam ( $this->_id_field ), $this->_request->getParams () );
			$this->_redirect ( $this->_default_action );
		} else {
			foreach ( $this->_validator->getErrors () as $key=>$error ) {
				$this->_messages->setMessage ( $error ,'error',$key);
			}
			$this->_formdata->request = $this->_request->getParams();
			$this->_redirect ( $this->_add_form_action . '?' . $this->_id_field . '=' . $this->_request->getParam ( $this->_id_field ) );
		}
	}
	/**
	 * Modifies specified node in a db
	 *
	 * @return void
	 */
	public function editnodeAction() {
		if ($this->_validator->validate ( $this->_formname, $this->_request->getParams () )) {
			$this->_tree->editNode ( $this->_request->getParam ( $this->_id_field ), $this->_request->getParams () );
		} else {
			foreach ( $this->_validator->getErrors () as $key=>$error ) {
				$this->_messages->setMessage ( $error,'error',$key);
			}
			$this->_redirect ( $this->_edit_form_action . '?' . $this->_id_field . '=' . $this->_request->getParam ( $this->_id_field ) );
		}
		$this->_redirect ( $this->_default_action );
	}	
	/**
	 * Deletes specified tree branch or node
	 *
	 * @return void
	 */
	public function deletebranchAction() {
		$this->_tree->deleteNode ( $this->_request->getParam ( $this->_id_field ) );
		$this->_redirect ( $this->_default_action );
	
	}	
	/**
	 * Moves up node in a tree branch limits
	 * 
	 * @return void
	 */
	public function moveupAction() {
		$this->_tree->ChangePositionAll ( $this->_request->getParam ( $this->_id_field ), $this->_request->getParam ( 'nnode_id' ), 'before' );
		$this->_redirect ( $this->_default_action );
	}	
	/**
	 * Moves down node in a tree branch limits
	 *
	 * @return void
	 */
	public function movedownAction() {
		$this->_tree->ChangePositionAll ( $this->_request->getParam ( $this->_id_field ), $this->_request->getParam ( 'nnode_id' ), 'after' );
		$this->_redirect ( $this->_default_action );
	}	
	/**
	 * Displays form to move node into any tree branch 
	 *
	 * @return void
	 */
	public function moveformAction() {
		$alltree = $this->_tree->getTree ();
		$node_id = $this->_request->getParam ( $this->_id_field );
		$this->view->assign ( $this->_id_field, $node_id );
		$this->view->assign ( 'tree', $alltree );
		$this->view->display ( $this->_move_form_template );
	}	
	/**
	 * Moves node into any tree branch
	 *
	 * @return void
	 */
	public function movenodeAction() {
		if (! $this->_tree->moveNode ( $this->_request->getParam ( $this->_id_field ), $this->_request->getParam ( 'parent_id' ) )) {
			foreach ( $this->_tree->getErrors () as $error ) {
				$this->_messages->setMessage ( $this->_texts->$error );
			}
		}		
		$this->_redirect ( $this->_default_action );
	}
}